import os
from multiprocessing import Process
from mitmproxy.tools import main
import subprocess

from zz import zz_sys_proxy, zz_log, zz_return, zz_str

log = zz_log.of()
# 获取证书 http://mitm.it/

proxy = None

msg_file_path = "proxy_msg.txt"


def is_cert_installed():
    """
    判断证书是否安装
    """
    try:
        # 使用certutil命令查询证书存储
        result = subprocess.run(['certutil', '-store', 'root'], capture_output=True, text=True, check=True)
        # 检查输出中是否包含mitmproxy
        if 'mitmproxy' in result.stdout:
            return True
        else:
            return False
    except Exception as e:
        print(f"Error checking certificate installation: {e}")
        return False


def get_msg():
    """
    获取消息
    """
    txt = ''
    try:
        with open(msg_file_path, 'r', encoding='utf-8') as file:
            lines = file.readlines()
            for line in lines:
                txt += line
    except Exception as ex:
        log.error(f"读取文件失败：{ex}")
    finally:
        os.remove(msg_file_path)

    return zz_return.parse(txt)


def save_msg(r: zz_return.Return):
    """
    保存消息
    """
    if exists_msg():
        # 消息已存在，需要先读取后，才能继续保存
        return
    #
    config = r.to_json()
    file = open(msg_file_path, "w", encoding="utf-8")
    # 写入数据
    file.write(config)
    # 关闭文件
    file.close()


def exists_msg():
    """
    存在未读消息
    """
    return os.path.exists(msg_file_path)


def of(allow_hosts=None, file_path=None, port=5088):
    global proxy
    if proxy is not None:
        return proxy

    proxy = ZZ_Proxy(allow_hosts, file_path, port)
    return proxy


class ZZ_Proxy:
    def __init__(self, allow_hosts, file_path, port):
        if allow_hosts is None:
            raise ValueError("miss allow_hosts")

        self.allow_hosts = allow_hosts
        self.port = port
        self.file_path = file_path

    def get_option(self):
        option = [
            # '-s', self.file_path,
            '--listen-host', '0.0.0.0', '-p', f'{self.port}',
            '--set', 'block_global=false',  # 若不加，则只能本地拦截，而移动设备请求无法被拦截
            # '--set', 'allow_hosts=lai-m.com',  # 设置允许域名
            '--set', 'body-size-limit=10k',  # 只处理10K内的请求
            '-q',  # 屏蔽mitmdump默认的控制台日志，只显示自己脚本中的
        ]
        if zz_str.has_any_text(self.file_path):
            option.append('-s')
            option.append(self.file_path)

        # 设置允许域名
        if self.allow_hosts:
            for host in self.allow_hosts:
                option.append('--set')
                option.append(f'allow_hosts={host}')

        log.debug(f'{option}')
        return option

    def start_mitmproxy(self):
        option = self.get_option()
        # print(option)

        main.mitmdump(option)

    @staticmethod
    def get_pid(port):
        """
        获取监听程序pid，开启失败返回空
        """
        result = os.popen(f'netstat -ano | findstr {port} | findstr LISTENING')
        pid = result.read().split('      ')[-1]
        return pid.strip()

    @staticmethod
    def is_running(port):
        """
        运行中
        """
        pid = ZZ_Proxy.get_pid(port)
        if pid:
            return True
        return False

    def start_listen(self) -> Process:
        """
        开启监听
        """
        p = Process(target=self.start_mitmproxy, name='mitmproxy')
        p.start()
        self.set_sys_proxy()
        return p

    def set_sys_proxy(self):
        """
        设置系统代理
        """
        zz_sys_proxy.set_sys_proxy(f'127.0.0.1:{self.port}')

    def close_listen(self):
        """
        关闭监听
        """
        zz_sys_proxy.close_sys_proxy()
        pid = ZZ_Proxy.get_pid(self.port)
        log.debug(f"taskkill pid {pid}")
        if pid:
            os.popen(f'taskkill /f -t /pid {pid}')
